package ltd.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import ltd.handler.MyChannelHandler;
import ltd.helper.ConfigHelper;
import ltd.helper.RSAHelper;
import ltd.helper.SpringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 登录处理服务器 入口
 * Created by chinalin on 2017/3/31.
 */
public class ServerMain {
    private static Logger LOGGER = LoggerFactory.getLogger(ServerMain.class);

    public static int PORT ;	//端口号
    public static int RSA_KEYSIZE ;//RSA密钥位数
    public static boolean AUTO_REG ;//是否自动注册用户

//========================================================================================
    public static void main(String[] args) {
        LOGGER.info("========== ######## 配置初始化登录服务器 ######## ==========");
        //初始化配置文件
        initConfig();
        //初始化Spring框架
        SpringHelper.init();
        //初始化RSA密码器
        RSAHelper.initKey(RSA_KEYSIZE);

        LOGGER.info("========== ######## 启动登录服务器 ######## ==========");
        //bossGroup收到请求之后叫workerGroup去处理,
        EventLoopGroup bossGroup = new NioEventLoopGroup();//用于接受请求的线程组
        EventLoopGroup workerGroup = new NioEventLoopGroup();//用于处理IO操作线程组
        // NIO服务器端的辅助启动类
        ServerBootstrap bootstrap = new ServerBootstrap();
        try {
            bootstrap.handler(new LoggingHandler(LogLevel.INFO));//配置日志输出
            bootstrap.group(bossGroup, workerGroup);
            bootstrap.channel(NioServerSocketChannel.class);// 设置NIO类型的channel
            bootstrap.option(ChannelOption.SO_BACKLOG, 1024);// 配置TCP参数
            bootstrap.childHandler(new MyChannelHandler());// 最后绑定I/O事件的处理类，处理网络IO事件
            // 服务器启动后 绑定监听端口 同步等待成功 主要用于异步操作的通知回调 回调处理用的ChildChannelHandler
            ChannelFuture f = bootstrap.bind(PORT).sync();// 配置完成，开始绑定server，通过调用sync同步方法阻塞直到绑定成功
            f.channel().closeFuture().sync();// 应用程序会一直等待，直到channel关闭
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //释放线程池资源
            bossGroup.shutdownGracefully();
            workerGroup.shutdownGracefully();
            LOGGER.info("...!!! 登录服务器已经关闭 !!!...");
        }
    }

    /** 初始化相关配置 */
    private static void initConfig() {
        PORT = ConfigHelper.getPort() ;
        RSA_KEYSIZE = ConfigHelper.getRsaKeySize() ;
        AUTO_REG = ConfigHelper.getAutoRegister() ;
        LOGGER.info("登录服务器 端口号：" + PORT + "  RSA密钥位数：" + RSA_KEYSIZE + " 是否自动注册用户：" + AUTO_REG );
    }
}
